package gui;

import geodata.BoreData;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import record.ProjectRecord;
import request.Request;
import request.RequestFactory;
import request.RequestType;
import request.SaveRequest;
import system.Client;

/**
 * A window that represents the Bore Requirements for the project to the user
 * @author Stephan Jossie
 * @author Jacob Freemyer
 *
 */
public class BoreRequirementsWindow extends JPanel implements ActionListener
{
	/**
	 * Serialized
	 */
	private static final long serialVersionUID = 2680880733289226535L;
	
	/**
	 * The Client of the Application
	 */
	private Client client;
	/**
	 * The Record that is used to update Bore Data
	 */
	private ProjectRecord record;
	/**
	 * A reference to the Application the window will be in
	 */
	private Application app;
	
	/**
	 * Information from user on thermal conductivity
	 */
	private JTextField thermalConductivity;
	/**
	 * Information from user on volumetric heat capacity
	 */
	private JTextField volumetricHeatCapacity;
	/**
	 * Information from user on thermal resistance
	 */
	private JTextField thermalResistance;
	/**
	 * Information from user on bore depth
	 */
	private JTextField boreDepth;
	
	/**
	 * Reference to done button to see event
	 */
	private JButton doneButton;
	
	private RequestFactory factory = new RequestFactory();
	
	
	
	/**
	 * Creates an instance of the BoreRequirementsWindow and initializes the window
	 * @param record
	 * 		The record to initialize the data from
	 * @param pApp
	 * 		The application in which the window is being displayed
	 */
	public BoreRequirementsWindow(ProjectRecord record, Application pApp)
	{
		this.client = pApp.getClient();
		this.record = record;
		
		thermalConductivity = new JTextField();
		volumetricHeatCapacity = new JTextField();
		thermalResistance = new JTextField();
		boreDepth = new JTextField();
		
		thermalConductivity.setInputVerifier(new DoubleVerifier());
		volumetricHeatCapacity.setInputVerifier(new DoubleVerifier());
		thermalResistance.setInputVerifier(new DoubleVerifier());
		boreDepth.setInputVerifier(new DoubleVerifier());
		
		JPanel inputPanel = new JPanel(new GridLayout(4, 2, 5, 5));
		inputPanel.add(new JLabel("Thermal Conductivity:"));
		inputPanel.add(thermalConductivity);
		inputPanel.add(new JLabel("Volumetric Heat Capacity:"));
		inputPanel.add(volumetricHeatCapacity);
		inputPanel.add(new JLabel("Thermal Resistance"));
		inputPanel.add(thermalResistance);
		inputPanel.add(new JLabel("Bore Depth:"));
		inputPanel.add(boreDepth);
		
		doneButton = new JButton("Done");
		doneButton.addActionListener(this);
		
		this.add(inputPanel);
		this.add(doneButton);
		
		initValues();
		
		app = pApp;
		app.getContentPane().removeAll();
		app.getContentPane().add(this);
		app.setVisible(true);
		
		
	}
	

	/**
	 * Initializes the value fields of Bore Requirements
	 */
	private void initValues()
	{
		BoreData bores = record.getBoreData();
		
		if(bores == null)
			return;
		
		
		thermalConductivity.setText("" + bores.getFieldByName("Thermal Conductivity").getValue().toString());
		volumetricHeatCapacity.setText("" + bores.getFieldByName("Volumetric Heat Capacity").getValue().toString());
		thermalResistance.setText("" + bores.getFieldByName("Thermal Resistance").getValue().toString());
		boreDepth.setText("" + bores.getFieldByName("Bore Depth").getValue().toString());
	}

	/**
	 * Saves the data to the ProjectRecord
	 */
	private void saveValues()
	{
		BoreData bores = record.getBoreData();
		record.setBoreRequirementsComplete(true);
		
		bores.getFieldByName("Thermal Conductivity").setValue((Double.parseDouble(thermalConductivity.getText())));
		bores.getFieldByName("Volumetric Heat Capacity").setValue((Double.parseDouble(volumetricHeatCapacity.getText())));
		bores.getFieldByName("Thermal Resistance").setValue(Double.parseDouble(thermalResistance.getText()));
		bores.getFieldByName("Bore Depth").setValue((Double.parseDouble(boreDepth.getText())));
	}

	/** 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent arg0)
	{
		if(arg0.getSource().equals(doneButton))
		{
			saveValues();
			try
			{
				SaveRequest save = (SaveRequest) factory.getRequest(RequestType.Save);
				save.setRecord(record);
				client.sendRequest(save);
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			catch (ClassNotFoundException e)
			{
				e.printStackTrace();
			}
			new ProjectMenuWindow(record, app);
		}
	}

	/**
	 * Verifies that the user has entered valid doubles
	 * @author Stephan Jossie
	 *
	 */
	class DoubleVerifier extends InputVerifier
	{
		/**
		 * @see InputVerifier#verify(JComponent)
		 */
		// Return true if there is a valid double that is greater than or equal to 0
		@Override
		public boolean verify(JComponent input)
		{
			if(((JTextField)input).getText().equals(""))
				return true;
			try
			{
				double d = Double.parseDouble(((JTextField)input).getText());
				return d >= 0;
			}
			catch(NumberFormatException e)
			{
				return false;
			}
		}
		
		/**
		 * @see InputVerifier#shouldYieldFocus(JComponent)
		 */
		// Provides a visual indication that the user has f*ed up
		@Override
		public boolean shouldYieldFocus(JComponent input)
		{
			boolean retval = super.shouldYieldFocus(input);
			
			if(retval)
				input.setBackground(Color.WHITE);
			else
				input.setBackground(Color.YELLOW);
			
			return retval;
		}
	} // End inner class
}
